import type { ComponentStyleIdType, PlatformTypeValue } from '../../../types/interfaces'
import { BaseModule } from '../../../lib/abstract'
import { PageHandler } from '../../../lib/page_handler'
import { GiteePageType } from '../../../lib/page_handler/platform/gitee/types'
import { PollingHandler } from '../../../lib/polling_handler'
import { ToolKit } from '../../../lib/utils/toolkit'
import {
  ComponentStyleId,
  HOSTNAME,
  logger,
  PROJECT_PREFIX,
  SUPPORTED_PLATFORMS,
  TIME_UNITS,
} from '../../../types/constants'
import { SYMBOLS } from '../../../types/interfaces'
import { ConfigManager } from '../../config_manager'

interface Config {
  enabled?: boolean
  recentTime: number
}

interface DirTimeSimplifierConfig {
  selector: string
  time: ($element: JQuery<HTMLElement>) => number
  listen?: boolean
}

type DirTimeSimplifierPlatformConfig = Partial<Record<PlatformTypeValue, Record<string, DirTimeSimplifierConfig>>>

interface DirTimeSimplifierInfo {
  element: JQuery<HTMLElement>
}

export class DirTimeSimplifier extends BaseModule {
  readonly id: string = 'dir_time_simplifier'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  private static instance: DirTimeSimplifier
  private readonly className: string = `${PROJECT_PREFIX}-dir-time-simplifier`
  private readonly configManager: ConfigManager = ConfigManager.getInstance()
  readonly supportedPlatforms: string[] = this.configManager.moduleSupportedPlatforms(this.name)

  get currentConfig(): DirTimeSimplifierConfig | undefined {
    return this.getCurrentConfig()
  }

  // 存储处理过的提交信息
  private processedDirs: Map<JQuery<HTMLElement>, DirTimeSimplifierInfo> = new Map()

  config: Config = {
    enabled: true,
    recentTime: TIME_UNITS.COMMON.INTERVALS.ONE_DAY,
  }

  get name(): ComponentStyleIdType {
    return 'DirTimeSimplifier'
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): DirTimeSimplifier {
    if (!DirTimeSimplifier.instance) {
      DirTimeSimplifier.instance = new DirTimeSimplifier()
    }
    return DirTimeSimplifier.instance
  }

  handleCleanupOthers(): void {
    this.cleanup()
  }

  handleCleanupReferences(): void {
    this.processedDirs.clear()
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.applyDirTimeSimplifier()
  }

  onToggleCallback(_id: string, checked: boolean, first: boolean): void {
    super.onToggleCallback(_id, checked, first)
  }

  /**
   * 获取当前页面的配置
   */
  getCurrentConfig(): DirTimeSimplifierConfig | undefined {
    const config: DirTimeSimplifierPlatformConfig = {
      [SUPPORTED_PLATFORMS.GITEE]: {
        [GiteePageType.Project]: {
          selector: '#tree-slider .tree-item .tree_time_ago',
          time: ($element: JQuery<HTMLElement>) => {
            const $timeElement = $element.find('.timeago')
            return ToolKit.time.parseTimestamp($timeElement.attr('datetime') || '')
          },
          listen: true,
        },
      },
    }

    const currentConfig = config[HOSTNAME]?.[PageHandler.getCurrentPageType()]

    if (!currentConfig) {
      logger.warn(`[${this.name}] 未找到当前页面类型的配置`)
    }

    return currentConfig
  }

  applyDirTimeSimplifier(): void {
    if (!this.currentConfig)
      return

    this.cleanup()

    const { selector, time, listen } = this.currentConfig

    const handler = () => {
      const $elements = $(selector)
      const elementCount = $elements.length
      let processedCount = 0

      if (elementCount === 0) {
        logger.notice(`[${this.name}] ${SYMBOLS.STATUS.WARNING} 未找到目录时间元素，跳过处理`, selector)
        return
      }

      $elements.each((_index, element) => {
        const $element = $(element)

        if (this.processDirTimeElement($element, time($element)))
          processedCount++
      })

      logger.info(`[${this.name}] ${SYMBOLS.STATUS.SUCCESS} 已隐藏 ${processedCount} 个目录时间元素`)
    }

    if (!listen) {
      handler()
    }
    else {
      const pollingHandler = new PollingHandler()
      pollingHandler.api.awaitElement(selector, handler)
    }
  }

  /**
   * 处理目录元素
   */
  processDirTimeElement($element: JQuery<HTMLElement>, time: number): boolean {
    const interval = Date.now() - time

    if (interval < this.config.recentTime)
      return false

    $element.addClass(`${this.className}`)
    ToolKit.dom.showControl($element, { show: false })

    this.processedDirs.set($element, {
      element: $element,
    })

    return true
  }

  /**
   * 移除现有图标
   */
  private removeExistingIcon(): void {
    const $processedElements = $(`${this.currentConfig?.selector || ''}`).filter(`.${this.className}`)

    $processedElements.removeClass(`${this.className}`)
    ToolKit.dom.showControl($processedElements, { show: true })
  }

  /**
   * 清理操作
   */
  private cleanup(): void {
    this.removeExistingIcon()
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.applyDirTimeSimplifier()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }
}
